package com.hph.demo;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.bytes.ByteArrayDecoder;
import io.netty.handler.codec.bytes.ByteArrayEncoder;

import java.util.concurrent.TimeUnit;

/**
 * Netty 客户端
 *
 * @author 10499
 */
public class NettyClientDemo {

    public static void main(String[] args) throws InterruptedException {

        // 创建客户端启动对象
        Bootstrap bootstrap = new Bootstrap();
        NioEventLoopGroup nioEventLoopGroup = new NioEventLoopGroup();
        // 配置
        bootstrap.group(nioEventLoopGroup)
                .channel(NioSocketChannel.class)
                .handler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel ch) throws Exception {
                        ChannelPipeline pipeline = ch.pipeline();
                        // 设置编码器
                        pipeline.addLast(new ByteArrayDecoder());
                        pipeline.addLast(new ByteArrayEncoder());
                        pipeline.addLast(new MySocketChannelHandler());
                    }
                });
        ChannelFuture channelFuture = connect(bootstrap);
        System.out.println("客户端已启动！！！");
        channelFuture.channel().closeFuture().sync();
    }

    private static ChannelFuture connect(Bootstrap bootstrap) {
        ChannelFuture channelFuture = bootstrap.connect("127.0.0.1", 8888);
        channelFuture.addListener((future) -> {
            if (!future.isSuccess()) {
                // 如果连接失败的话，设置过一秒重连一次
                channelFuture.channel().eventLoop().schedule(() -> {

                    System.out.println("未连接成功，尝试重连中。。。。");
                    connect(bootstrap);
                }, 3000, TimeUnit.MILLISECONDS);
            }
        });
        return channelFuture;
    }

    static class MySocketChannelHandler extends ChannelInboundHandlerAdapter {

        @Override
        public void channelActive(ChannelHandlerContext ctx) throws Exception {

            System.out.println("已连接！！！");
            Channel channel = ctx.channel();
            channel.writeAndFlush(ProtostuffUtils.serialize(new User("hph", 18)));
        }

        @Override
        public void channelInactive(ChannelHandlerContext ctx) throws Exception {

            System.out.println("已下线！！！");
        }
    }
}
